主题
日志 Skin 回调类型 - OLALogSkinCallback
类型简介
OLALogSkinCallback 是自定义日志 Skin 的回调函数类型。通过 LogRegisterSkin 全局注册后,当某个日志实例的 LogSetTarget 包含该 Skin 返回的位枚举值时,每条通过 LogSetLevel 过滤的日志都会触发本回调。
被级别过滤掉的日志不会进入 sink,因此也不会触发本回调。
典型用途:
- 推送到自研 UI 列表 / 悬浮窗
- 转发到网络、数据库或第三方监控
- 与文件 / 控制台并行输出,互不影响
类型定义
cpp
typedef void (OLA_CALL_TYPE* OLALogSkinCallback)(
int32_t level,
OLA_STRING_INPUT rawMessage,
OLA_STRING_INPUT formattedMessage,
int64_t userData);头文件:model/ola_callback.h(由 olaplug/ola_logger.h 间接包含)。
参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| level | 整数型 | 日志级别:0=TRACE … 5=CRITICAL,6=OFF。 |
| rawMessage | OLA_STRING_INPUT (void*) | 原始日志内容(未套用 pattern)。仅回调期间有效。 |
| formattedMessage | OLA_STRING_INPUT (void*) | 已套用 LogSetPattern 的完整行。仅回调期间有效。 |
| userData | 长整数型 | LogRegisterSkin 注册时传入的上下文,可为 0。 |
字符串编码(兼容 EncodeFormat / DefaultReturnEncoding)
插件内部日志内容为 UTF-8;回调传出前按 DefaultReturnEncoding(与 API 返回字符串同一套规则)转换:
| DefaultReturnEncoding | 指针实际类型 | 说明 |
|---|---|---|
0 | char*(GBK) | 与返回字符串 GBK 模式一致 |
1(默认) | char*(UTF-8) | 与返回字符串 UTF-8 模式一致 |
2 | wchar_t*(Unicode) | 与返回字符串 Unicode 模式一致 |
写入侧仍走 EncodingConversion::FormatInput(按 DefaultEncoding 把输入转成内部 UTF-8),因此「写日志输入编码」与「Skin 回调输出编码」分别对应 DefaultEncoding / DefaultReturnEncoding。
返回值
无(void)。
调用约定(x86 / x64)
| 项目 | 说明 |
|---|---|
| C/C++ | 回调必须使用 OLA_CALL_TYPE(__stdcall)。 |
| x86 | stdcall 与 cdecl 不同,漏写 stdcall 会导致栈不平衡崩溃。 |
| x64 | MSVC 忽略 stdcall 修饰,与默认约定等价;仍建议统一写 OLA_CALL_TYPE,保证双架构同一份源码。 |
| C# | [UnmanagedFunctionPointer(CallingConvention.StdCall)];COM/DLL 传入 IntPtr.ToInt64()(x86 上高 32 位为 0)。 |
示例
回调本体(须 OLA_CALL_TYPE / StdCall):
cpp
#include "olaplug/ola_logger.h"
#include <cstdio>
void OLA_CALL_TYPE OnUiLog(int32_t level, void* rawMessage, void* formattedMessage,
int64_t userData) {
(void)userData;
// DefaultReturnEncoding==1 时按 UTF-8 读;==2 时请按 wchar_t* 读
const char* raw = rawMessage ? static_cast<const char*>(rawMessage) : "";
const char* formatted =
formattedMessage ? static_cast<const char*>(formattedMessage) : "";
std::printf("[skin] level=%d raw=%s formatted=%s\n", level, raw, formatted);
}csharp
using System;
using System.Runtime.InteropServices;
using System.Text;
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
delegate void LogSkinCallback(int level, IntPtr rawMessage, IntPtr formattedMessage,
long userData);
// DefaultReturnEncoding==1(UTF-8)示例
void OnUiLog(int level, IntPtr rawMessage, IntPtr formattedMessage, long userData)
{
string raw = Marshal.PtrToStringUTF8(rawMessage) ?? "";
string formatted = Marshal.PtrToStringUTF8(formattedMessage) ?? "";
Console.WriteLine($"[skin] level={level} raw={raw} formatted={formatted}");
}完整联动(注册 → 勾选目标 → 写日志),详见 LogRegisterSkin:
cpp
#include "OLAPlugServer.h"
OLAPlugServer ola;
int skin = ola.LogRegisterSkin((int64_t)(void*)&OnUiLog, 0);
if (skin != 0) {
int64_t logger = ola.LogCreateInstance("UiLogger");
ola.LogSetAsync(logger, 0); // 测试建议同步,便于立刻收到回调
ola.LogSetTarget(logger, 1 | skin); // FILE | skin
ola.LogInfoEx(logger, "hello skin");
ola.LogFlush(logger);
ola.LogUnregisterSkin(skin);
ola.LogDestroyInstance(logger);
}注意事项
| 项目 | 说明 |
|---|---|
| 级别过滤 | LogSetLevel 过滤掉的记录不回调。 |
| 编码 | 跟随 DefaultReturnEncoding,与 EncodeFormat / 返回字符串一致。 |
| 进程内有效 | 函数指针,不支持跨进程 / 远程实例转发。 |
| 线程 | LogSetAsync=1 时可能在日志线程池触发。 |
| 禁止重入 | 回调内勿对同一 logger 调用 LogSetTarget / LogInfoEx 等,以免死锁。 |
| 快速返回 | 勿长时间阻塞;异常勿抛出到插件外。 |
| 字符串生命周期 | rawMessage / formattedMessage 仅回调期间有效。 |
相关接口
| 接口 | 说明 |
|---|---|
| LogRegisterSkin | 全局注册,返回位枚举。 |
| LogUnregisterSkin | 按位枚举注销。 |
| LogClearSkins | 清空全部全局 Skin。 |
| LogSetTarget | 将 Skin 位与 FILE/CONSOLE 组合到指定 logger。 |
| LogSetLevel | 级别过滤(过滤后不回调)。 |
